﻿///////////////////////////////////////////////////////////////////////////////
//
// This file is part of the BassDrop project
//   https://code.google.com/p/bass-drop/
//
//
// Creator:	Gergely Krajcsovszki (krajcsovszkig@hotmail.com)
// Date:	2013-08-26 12:30
//
//
// Copyright © 2013-2014. Gergely Krajcsovszki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///////////////////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using BassDrop.Core.Common;

namespace BassDrop.DesktopClient.UI.Views
{
	/// <summary>
	/// View / page for showing the application settings
	/// </summary>
	public partial class SettingsView : ContentViewBase
	{
		/// <summary>
		/// The currently selected content view panel
		/// </summary>
		private ContentViewBase m_selectedContentView;
		/// <summary>
		/// The currently selected content view panel
		/// </summary>
		private ContentViewBase SelectedContentView
		{
			get
			{
				return m_selectedContentView;
			}

			set
			{
				if ( m_selectedContentView != value )
				{
					m_selectedContentView = value;

					UpdateContent();
				}
			}
		}

		/// <summary>
		/// The instance of the "About" view
		/// </summary>
		private AboutView m_aboutView;

		/// <summary>
		/// The views in this settings. Keys are the objects they belong to.
		/// </summary>
		private Dictionary<object, TreeViewItem> m_views = new Dictionary<object, TreeViewItem>();

		/// <summary>
		/// Constructs a new Settings view
		/// </summary>
		public SettingsView()
		{
			m_aboutView = new AboutView();

			InitializeComponent();

			Controller.Instance.PluginManager.PluginsChanged += PluginManager_PluginsChanged;

			LayoutOptions();
			LayoutPlugins();
			UpdateContent();
		}

		/// <summary>
		/// Updates the content panel based on the SelectedContentView property
		/// </summary>
		private void UpdateContent()
		{
			if ( GridContentPanel == null )
			{
				return;
			}

			GridContentPanel.Children.Clear();

			if ( SelectedContentView != null )
			{
				GridContentPanel.Children.Add( SelectedContentView );
			}
		}

		private void LayoutOptions()
		{
			TreeViewOptionsPages.Items.Clear();

			foreach ( var optionsSet in Controller.Instance.ProgramOptions )
			{
				CustomOptionsView optionsView = new CustomOptionsView( optionsSet );
				TreeViewItem optionsTreeViewItem = new TreeViewItem();

				Binding headerTextBinding = new Binding();
				headerTextBinding.Source = optionsSet;
				headerTextBinding.Path = new PropertyPath( "Name" );
				BindingOperations.SetBinding( optionsTreeViewItem, TreeViewItem.HeaderProperty, headerTextBinding );

				optionsTreeViewItem.SetResourceReference( TreeViewItem.StyleProperty, "StyleGeneralTreeViewItem" );

				optionsTreeViewItem.Selected += ( sender, e ) =>
					{
						SelectedContentView = optionsView;
						e.Handled = true;
					};

				TreeViewOptionsPages.Items.Add( optionsTreeViewItem );
			}

			TreeViewOptionsPages.Items.Add( TreeViewItemPlugins );
			TreeViewOptionsPages.Items.Add( TreeViewItemAbout );
		}

		/// <summary>
		/// Lays out the list of plugins
		/// </summary>
		private void LayoutPlugins() // TODO: csoportosítva
		{
			object selectedItem = (from item
								   in m_views
								   where item.Value == TreeViewOptionsPages.SelectedItem
								   select item.Key).FirstOrDefault();

			TreeViewItemPlugins.Items.Clear();
			m_views.Clear();

			foreach ( var item in Controller.Instance.PluginManager.GetPlugins() )
			{
				var treeViewItem = new TreeViewItem();
				treeViewItem.Header = item.Name;
				treeViewItem.SetResourceReference( TreeViewItem.StyleProperty, "StyleGeneralTreeViewItem" );

				var view = new CustomOptionsView( item.Options );
				m_views[item] = treeViewItem;
				treeViewItem.Selected += ( sender, e ) =>
					{
						SelectedContentView = view;
						e.Handled = true;
					};

				foreach ( var instance in item.GetInstances() )
				{
					if ( instance.Options != null )
					{
						var instanceTreeViewItem = new TreeViewItem();
						instanceTreeViewItem.Header = instance.InstanceName;
						instanceTreeViewItem.SetResourceReference( TreeViewItem.StyleProperty, "StyleGeneralTreeViewItem" );

						var instanceView = new CustomOptionsView( instance.Options );
						m_views[instance] = instanceTreeViewItem;
						instanceTreeViewItem.Selected += ( sender, e ) =>
							{
								SelectedContentView = instanceView;
								e.Handled = true;
							};

						treeViewItem.Items.Add( instanceTreeViewItem );
					}
				}

				TreeViewItemPlugins.Items.Add( treeViewItem );
			}

			if ( selectedItem != null )
			{
				SelectViewForItem( selectedItem );
			}
		}

		/// <summary>
		/// Selects the view belonging to the item if there is one, does nothing otherwise.
		/// </summary>
		/// <param name="item"></param>
		public void SelectViewForItem( object item )
		{
			if ( m_views.ContainsKey( item ) )
			{
				m_views[item].IsSelected = true;

				var parent = m_views[item].Parent as TreeViewItem;

				while ( parent != null )
				{
					parent.IsExpanded = true;
					parent = parent.Parent as TreeViewItem;
				}
			}
		}

		#region Event handlers

		private void TreeViewItemAbout_Selected( object sender, RoutedEventArgs e )
		{
			SelectedContentView = m_aboutView;
			e.Handled = true;
		}

		private void TreeViewItemPlugins_Selected( object sender, RoutedEventArgs e )
		{
			// TODO: elérhető pluginok listája, aboutja
			SelectedContentView = null;
			e.Handled = true;
		}

		private void PluginManager_PluginsChanged( object sender, EventArgs e )
		{
			Dispatcher.Invoke( (Action) (() => LayoutPlugins()) );
		}

		#endregion Event handlers
	}
}
